﻿using IceCS.DataStructure.Core.LinearList.Exceptions;

namespace IceCS.DataStructure.Core.Stack
{
    /// <summary>
    /// 顺序栈
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SequenceStack<T> : IStack<T>
    {
        /// <summary>
        /// 存储数据
        /// </summary>
        private T[] _data;

        /// <summary>
        /// 数据表最大长度
        /// </summary>
        public int MaxCount { get; }
        /// <summary>
        /// 栈顶位置
        /// </summary>
        public int Top { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        public int Count { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        public bool IsEmpty => Top == -1;

        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T this[int index] => _data[index];

        /// <summary>
        /// 
        /// </summary>
        private SequenceStack()
        {
            Top = -1;
            MaxCount = 10;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="maxCount"></param>
        public SequenceStack(int maxCount)
        {
            _data = new T[maxCount];
            Top = -1;
            MaxCount = maxCount;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        public void Push(T data)
        {
            if (IsFull)
            {
                throw new DSFullException("堆栈已满，无法插入");
            }
            Top += 1;
            _data[Top] = data;
            Count++;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public T Pop()
        {
            if (IsEmpty)
            {
                return default;
            }
            var data = _data[Top];
            Top -= 1;
            Count--;
            return data;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public T GetTop()
        {
            if (IsEmpty)
            {
                return default;
            }
            return _data[Top];
        }

        /// <summary>
        /// 
        /// </summary>
        public void Clear()
        {
            Top = -1;
            Count = 0;
            _data = new T[MaxCount];
        }

        /// <summary>
        /// 
        /// </summary>
        public bool IsFull => MaxCount == Count;


    }
}
